package com.cloudpolice.door.unit;

import lombok.extern.log4j.Log4j2;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.FileImageInputStream;
import javax.imageio.stream.ImageInputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.*;

/**
 * 图片处理辅助类
 *
 * @author liaoyueli
 * @date 2020-04-15
 */
@Log4j2
public class ImageUtil {

    /**
     * 在图片上画一个或多个矩形框
     *
     * @param source 源图片地址
     * @param output 输出图片地址
     * @param coords 画框的坐标数据集
     * @return 布尔值，true-成功，false-失败
     */
    public static Boolean drawPicture(String source, String output, Map<Integer, String> coords) {
        boolean isSuccess = false;
        try {
            BufferedImage image = ImageIO.read(new File(source));
            // 画笔颜色
            Graphics g = image.getGraphics();
            g.setColor(Color.RED);

            // 在图片上画框
            String[] coord = null;
            for (Object value : coords.values()) {
                coord = value.toString().split(",");
                g.drawRect(Integer.valueOf(coord[0]), Integer.valueOf(coord[1]),
                        Integer.valueOf(coord[2]) - Integer.valueOf(coord[0]),
                        Integer.valueOf(coord[3]) - Integer.valueOf(coord[1]));
            }
            // 输出新图片
            FileOutputStream out = new FileOutputStream(output);
            ImageIO.write(image, "jpeg", out);
            isSuccess = true;
        } catch (IOException e) {
            log.error("在图片上画框时出错：" + e.getMessage(), e);
        }
        return isSuccess;
    }

    /**
     * 对图片进行裁剪，并将裁剪后的图片保存
     *
     * @param srcPath 源图片路径名称
     * @param subPath 剪切图片存放路径名称
     * @param x       剪切点x坐标
     * @param y       剪切点y坐标
     * @param width   剪切点宽度
     * @param height  剪切点高度
     */
    public static void cutPicture(String srcPath, String subPath, int x, int y, int width, int height) {
        FileInputStream is = null;
        ImageInputStream iis = null;
        try {
            // 读取图片文件
            is = new FileInputStream(srcPath);

            Iterator<ImageReader> it = ImageIO.getImageReadersByFormatName("jpg");
            ImageReader reader = it.next();
            // 获取图片流
            iis = ImageIO.createImageInputStream(is);
            reader.setInput(iis, true);

            Rectangle rect = new Rectangle(x, y, width, height);
            ImageReadParam param = reader.getDefaultReadParam();
            param.setSourceRegion(rect);
            BufferedImage bi = reader.read(0, param);

            // 保存新图片
            ImageIO.write(bi, "jpg", new File(subPath));
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                }
            }
            if (iis != null) {
                try {
                    iis.close();
                } catch (IOException e) {
                }
            }
        }
    }

    /**
     * 删除本地临时文件
     *
     * @param file 要删除的文件
     */
    public static void deleteTempFile(File file) {
        if (file != null) {
            File del = new File(file.toURI());
            if (del.delete()) {
                log.info("local file delete success!");
            }
        }
    }

    /**
     * 图片转化为byte数组
     *
     * @param path 图片路径
     * @return byte数组
     */
    public static byte[] image2byte(String path){
        byte[] data = null;
        FileImageInputStream input = null;
        try {
            input = new FileImageInputStream(new File(path));
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            byte[] buf = new byte[1024];
            int numBytesRead = 0;
            while ((numBytesRead = input.read(buf)) != -1) {
                output.write(buf, 0, numBytesRead);
            }
            data = output.toByteArray();
            output.close();
            input.close();
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        return data;
    }

    /**
     * 自动创建文件路径
     *
     * @param path 文件路径
     */
    public static void mkdir(String path) {
        File fd = null;
        try {
            fd = new File(path);
            if (!fd.exists()) {
                fd.mkdirs();
            }
        } catch (Exception e) {
            log.error("create File dir Exception", e);
        } finally {
            fd = null;
        }
    }

    public static void main(String[] args) {
        String result = "{\n" +
                "    \"data\": [\n" +
                "        {\n" +
                "            \"id\": \"2533347913891911\",\n" +
                "            \"sourceId\": \"2533306422374546\",\n" +
                "            \"sourceType\": 2,\n" +
                "            \"time\": 1587367524000,\n" +
                "            \"imageData\": \"/ifsrc/engine1/eng1store1_0/FaceWareHouse/src_2_0/20200420/20200420T152524_0_88_0.jpg\",\n" +
                "            \"race\": 0,\n" +
                "            \"fromImageId\": \"2533306422374546\",\n" +
                "            \"json\": \"{ \\\"Rect\\\":{ \\\"left\\\":265,\\\"top\\\":834,\\\"right\\\":352,\\\"bottom\\\":921}, \\\"FaceImageRect\\\":{ \\\"left\\\":222,\\\"top\\\":791,\\\"right\\\":395,\\\"bottom\\\":964},\\\"Confidence\\\":{\\\"Gender\\\":0,\\\"Glass\\\":0,\\\"Hat\\\":0,\\\"Race\\\":0,\\\"Mask\\\":0}, \\\"Pose\\\": {\\\"Pitch\\\":0, \\\"Roll\\\":0, \\\"Yaw\\\":0}}\",\n" +
                "            \"quality\": 0,\n" +
                "            \"sequence\": \"72\",\n" +
                "            \"score\": 0.0,\n" +
                "            \"type\": 2\n" +
                "        },\n" +
                "        {\n" +
                "            \"id\": \"2533347913891912\",\n" +
                "            \"sourceId\": \"2533306422374546\",\n" +
                "            \"sourceType\": 2,\n" +
                "            \"time\": 1587367524000,\n" +
                "            \"imageData\": \"/ifsrc/engine1/eng1store1_0/FaceWareHouse/src_2_0/20200420/20200420T152524_0_89_0.jpg\",\n" +
                "            \"race\": 0,\n" +
                "            \"fromImageId\": \"2533306422374546\",\n" +
                "            \"json\": \"{ \\\"Rect\\\":{ \\\"left\\\":439,\\\"top\\\":211,\\\"right\\\":560,\\\"bottom\\\":332}, \\\"FaceImageRect\\\":{ \\\"left\\\":379,\\\"top\\\":151,\\\"right\\\":620,\\\"bottom\\\":392},\\\"Confidence\\\":{\\\"Gender\\\":0,\\\"Glass\\\":0,\\\"Hat\\\":0,\\\"Race\\\":0,\\\"Mask\\\":0}, \\\"Pose\\\": {\\\"Pitch\\\":0, \\\"Roll\\\":0, \\\"Yaw\\\":0}}\",\n" +
                "            \"quality\": 0,\n" +
                "            \"sequence\": \"73\",\n" +
                "            \"score\": 0.0,\n" +
                "            \"type\": 2\n" +
                "        }\n" +
                "    ],\n" +
                "    \"errCode\": 0,\n" +
                "    \"maxPage\": 0,\n" +
                "    \"total\": 0,\n" +
                "    \"count\": 0\n" +
                "}";
        JSONObject jsonObject = JSONObject.fromObject(result);
        JSONArray jsonArray = jsonObject.getJSONArray("data");
        Map<Integer, String> faceImage = new HashMap<>(10);
        Map<Integer, String> coords = new HashMap<>(10);
        JSONObject json = null, rect = null;
        String imagePath = "";
        int i = 1, width, height;
        StringBuilder coord = null;
        for (Object o : jsonArray) {
            coord = new StringBuilder();
            imagePath = "D:\\" + RandomUtil.generateString(32) + i + ".jpg";
            jsonObject = (JSONObject) o;
            // 人脸库位置
            json = jsonObject.getJSONObject("json");
            // FaceImageRect - 大脸 （Rect - 小脸）
            String isFace = "0";
            if ("0".equals(isFace)) {
                rect = json.getJSONObject("Rect");
            } else {
                rect = json.getJSONObject("FaceImageRect");
            }

            // 计算人脸的宽度和高度
            width = rect.getInt("right") - rect.getInt("left");
            height = rect.getInt("bottom") - rect.getInt("top");

            // 截取人脸图片
            ImageUtil.cutPicture("D:\\000.jpg", imagePath, rect.getInt("left"), rect.getInt("top"),
                    width, height);
            faceImage.put(i, imagePath);

            coord.append(rect.getInt("left")).append(",").append(rect.getInt("top")).append(",")
                    .append(rect.getInt("right")).append(",").append(rect.getInt("bottom"));
            coords.put(i, coord.toString());

            i++;
        }
        imagePath = "D:\\" + RandomUtil.generateString(32) + ".jpg";
        ImageUtil.drawPicture("D:\\000.jpg", imagePath, coords);

        // 上传图片
        byte[] data = ImageUtil.image2byte(imagePath);
        log.info(data);

//        Map<String, Double> map = new HashMap<>(10);
//        map.put("281544274546365", 0.80695085);
//        map.put("563023807667857", 0.94695085);
//        map.put("593023807667801", 0.74695085);
//        // 降序
//        Map<String, Double> sorted = map.entrySet().stream()
//                .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
//                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
//                        (oldValue, newValue) -> oldValue, LinkedHashMap::new));
//        System.out.println(sorted.toString());
//
//        Double similarity = sorted.entrySet().stream().findFirst().get().getValue();
//        String faceId = sorted.keySet().stream().findFirst().get();
//        System.out.println("最大相似度：" + similarity + "，id：" + faceId);
//
//        // 升序
//        Map<String, Double> result2 = new LinkedHashMap<>();
//        map.entrySet().stream()
//                .sorted(Map.Entry.<String, Double>comparingByValue().reversed())
//                .forEachOrdered(x -> result2.put(x.getKey(), x.getValue()));
//        System.out.println(result2.toString());
    }
}
